Skip to main content

The Cardano UTxO model

Cardano's ledger is a set of unspent transaction outputs (UTxOs). A transaction consumes some UTxOs (inputs) and produces fresh ones (outputs). That's the entire state model. There's no global "account balance"; "balance" is just the sum of UTxOs you can spend.

A UTxO has four parts

FieldTypeRole
AddressAddressWhere the funds live. Determines who can spend.
ValueValueWhat's in the UTxO — ADA, native tokens, NFTs.
DatumOutputDatumOptional Datum, can be either missing, a hash of the datum (backwards compatibility only), or inline with the actual data present, effectively acts as a Optional<data> although with different contstructors
Reference scriptOptional<bytes>If present (Some constructor) it specifies the 28-length hash of the ref script attached to the utxo

Outputs that pay to a script address (an address whose payment credential is a ScriptHash) typically carry a datum — that's how the script remembers what state it's guarding across transactions. Since Plutus V3, the datum is no longer mandatory: a spend script can validate a UTxO with NoDatum provided its logic doesn't need any persisted state (for instance, when the decision depends only on the current transaction's inputs, outputs, and signatories). When a datum is present, the validator is responsible for treating it as input that must be checked, not as a trusted fact — past validation only guarantees the datum was accepted by whichever script wrote it.

What spending looks like

A transaction tx has:

  • inputs: List<TxIn> — UTxOs being consumed, by reference.
  • outputs: List<TxOut> — fresh UTxOs being produced.
  • mint: Value — tokens being minted or burned.
  • signatories: List<PubKeyHash> — who has signed.
  • ... plus fees, validity interval, certificates, governance, etc.

The transaction is valid if:

  1. Every script protecting an input or controlling a mint approves it.
  2. The values balance: sum(inputs.value) + mint == sum(outputs.value) + fee.
  3. Other ledger rules (signatures, time, slot limits, ...) are satisfied.

If any single rule fails — including any single script saying "no" — the whole transaction is rejected. There is no partial state on chain.

Where Pebble fits

Pebble compiles a contract declaration into a Plutus script: a small program that the Cardano ledger evaluates with the relevant context to produce true, false, or a failure. A script in Pebble can guard:

  • Spending a UTxO at a script address (spend methods).
  • Minting / burning tokens under a policy (mint).
  • Certifying delegations, registrations (certify).
  • Withdrawing rewards (withdraw).
  • Governance: propose, vote.

These six script purposes are the six method-kinds inside contract { ... }. One Pebble contract can compile to a single script that handles several or all of them.

Datums vs redeemers

ConceptLives inSet byWhenPebble term
DatumA UTxO (output)The output's creatorAt UTxO creation timestate fields, or raw data in OutputDatum
RedeemerA spend / mint / ... actionThe transaction submitterWhen the action is attemptedMethod arguments

A datum is per-UTxO state: "this order wants 100 USDC at minimum". A redeemer is per-action intent: "fill the order with input index 2 and output index 3". Together they pin down exactly what the script must check.

Reference inputs

A transaction can include reference inputs: UTxOs it reads but does not consume. They're how you publish on-chain data once and have many transactions read it without paying to spend it. Oracle outputs, registry entries, and stored scripts (reference scripts) all use them.

In a Pebble validator, you can read reference inputs via tx.referenceInputs: List<TxIn>.

Determinism

Cardano transactions are deterministic: given a transaction and ledger state, every node reaches the same accept/reject decision and the same script budget. There's no on-chain randomness, no concurrency, no network calls. A validator that runs today will run identically tomorrow against the same inputs.

This determinism is why off-chain code (e.g. @harmoniclabs/buildooor) can construct a transaction, predict the exact script execution, and submit it with confidence.

See also